package com.merry.poi;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;

/**
 * @author zouyb
 * Excel的写入可以简单分为：
 *      1.创建一个工作簿：WorkBook
 *      2.创建一个sheet：
 *      3.创建一行row：
 *      4.创建一个单元格Cell：
 */
public class ExcelWriteDemo {
    public static void main(String[] args) throws Exception {
        ExcelWriteDemo excelWriteDemo = new ExcelWriteDemo();
        excelWriteDemo.write03();
        excelWriteDemo.write07();
        excelWriteDemo.batchWrite03();
        excelWriteDemo.batchWrite07();
        excelWriteDemo.batchWriteSXSSF();
    }

    //03版本写入
    public void write03() throws Exception {
        //1.创建工作簿 03版本用的是 HSSF模板
        HSSFWorkbook workbook = new HSSFWorkbook();
        //2.创建工作表
        HSSFSheet sheet = workbook.createSheet("03版本工作表1");
        //3.创建行(第一行)
        HSSFRow row = sheet.createRow(0);
        //4.创建单元格(第一个单元格)
        HSSFCell cell = row.createCell(0);
        //5.写入数据
        cell.setCellValue("商品ID");
        //后续操作。。。
        HSSFCell cell2 = row.createCell(1);
        cell2.setCellValue("商品名称");

        //生成一张表
        FileOutputStream fileOutputStream = new FileOutputStream("./03版本测试.xls");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        System.out.println("03表格生成完毕");

    }


    //07版本写入
    public void write07() throws Exception {
        //1.创建工作簿 07版本用的是 XSSF模板
        XSSFWorkbook workbook = new XSSFWorkbook();
        //2.创建工作表
        XSSFSheet sheet = workbook.createSheet("07版本工作表1");
        //3.创建行(第一行)
        XSSFRow row = sheet.createRow(0);
        //4.创建单元格(第一个单元格)
        XSSFCell cell = row.createCell(0);
        //5.写入数据
        cell.setCellValue("商品ID");
        //后续操作。。。
        XSSFCell cell2 = row.createCell(1);
        cell2.setCellValue("商品名称");

        //生成一张表
        FileOutputStream fileOutputStream = new FileOutputStream("./07版本测试.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        System.out.println("07版本表格生成完毕");
    }

    //03版本批量写入 速度比较快，但是最多只能写入 65536条数据
    public void batchWrite03() throws Exception {
        //开始时间
        long start = System.currentTimeMillis();
        //创建工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建表
        HSSFSheet sheet = workbook.createSheet("03");
        //写入数据
        for (int rowNum = 0; rowNum<65536; rowNum++){
            HSSFRow row = sheet.createRow(rowNum);
            for (int cellNum = 0;cellNum<20;cellNum++){
                HSSFCell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum+1);
            }
        }
        //生成表
        FileOutputStream fileOutputStream = new FileOutputStream("./03batchwrite.xls");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("03时间为"+(end-start));  // 03时间为1837
    }

    //07版本批量写入  速度慢，但是可以写入很多条数据。
    public void batchWrite07() throws Exception {
        //开始时间
        long start = System.currentTimeMillis();
        //创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        //创建表
        XSSFSheet sheet = workbook.createSheet("03");
        //写入数据
        for (int rowNum = 0; rowNum<65536; rowNum++){
            XSSFRow row = sheet.createRow(rowNum);
            for (int cellNum = 0;cellNum<20;cellNum++){
                XSSFCell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum+1);
            }
        }
        //生成表
        FileOutputStream fileOutputStream = new FileOutputStream("./07batchwrite.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("07时间为"+(end-start));  // 07时间为7286
    }


    /**
     * 大数据写SXSSF：为了解决大数据量写入的问题，所以官方提供了SXSSF来解决大文件写入的问题，
     * 比如写入上百万的数据时，可以使用SXSSF，写入速度更快，占用内存可以控制。
     * @throws Exception
     */
    public void batchWriteSXSSF() throws Exception {
        //开始时间
        long start = System.currentTimeMillis();
        //创建工作簿
        //在new的时候可以指定一个滑动窗口，默认是100，当内存中的数据超过100行时，就写入磁盘中，这样可以实现在小内存中完成Excel的导出。
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);
        //创建表
        SXSSFSheet sheet = workbook.createSheet("03");
        //写入数据
        for (int rowNum = 0; rowNum<65536; rowNum++){
            SXSSFRow row = sheet.createRow(rowNum);
            for (int cellNum = 0;cellNum<20;cellNum++){
                SXSSFCell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum+1);
            }
        }
        //生成表
        FileOutputStream fileOutputStream = new FileOutputStream("./sxssfbatchwrite.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("SXSSF时间为"+(end-start));  // SXSSF时间为2696
    }
}
